-- 运营活动: 许愿井


--[[
{
    cmd_id = 1, -- 命令id，用于批量停止、删除活动 
    act_id = 41, -- 活动id (41 许愿井)
    act_name = "许愿井", -- 活动名称
    act_desc = "活动期间获取经验达到对应档次则可领取丰厚奖励！", -- 活动描述
    beg_time = 1493262000,  -- 活动开始时间(unix timestamp)
    end_time = 1593267400,  -- 活动结束时间(unix timestamp)
    config = -- 配置数据
    {
        everyCountPerSecond = 1800, --多少秒增加一次 
        maxCount = 10,  --最大次数
        saveCount = 50, --保存最多信息
        itemList =  
        {   
            { weight = 1, type = 0, id = 508, count = 2,},
            { weight = 1, type = 0, id = 571, count =30,},
            { weight = 1, type = 0, id = 563, count = 3,},
            { weight = 1, type = 0, id = 558, count = 3,},
            { weight = 1, type = 0, id = 568, count = 3,},
            { weight = 1, type = 0, id = 524, count = 2,},
            { weight = 1, type = 0, id = 529, count = 2,},
            { weight = 1, type = 0, id = 534, count = 2,},
            { weight = 1, type = 0, id = 539, count = 2,},
            { weight = 1, type = 0, id = 763, count =10,},
            { weight = 1, type = 0, id = 509, count = 1,},
        },  
    },
}
]]

-- 检查配置是否正确，正确则返回 0，否则返回错误码
function oper_act_41_check_cfg(cfg)
    if cfg == nil then return 20 end
    
    local config = cfg.config
    if config == nil then return 21 end
    
    if config.itemList == nil then return 23 end
    if type(config.itemList) ~= "table" then return 24 end
   
    if not oper_act_check_one_award_cfg(config.itemList) then
        return 22
    end 

    return 0
end

-- 安装活动，成功则返回 0，否则返回错误码
function oper_act_41_setup(cfg) 
    return 0
end

-- 卸载活动
function oper_act_41_unsetup(cfg)   
end

-- 活动开始
function oper_act_41_start(cfg)
    local ssVar = System.getStaticVar()
    ssVar.oper_act_41_start = 1
    ssVar.oper_act_41_cmd = cfg.cmd_id
    ssVar.oper_act_41_act = cfg.act_id

    local data = gRankMgr_GetValueByIndx(0, RANK_DEFINE_OPERATION_41, 1)

    local needClearState = true

    local crossDayState = false

    if data then
        local myData = BaseFuc_unserialize(data)
        if myData and myData.cmd_id and myData.cmd_id == cfg.cmd_id and myData.act_id and myData.act_id == cfg.act_id and
            myData.time and cfg.beg_time <= myData.time and  cfg.end_time > myData.time then
            needClearState = false
            local time = System.getSystemTime()
            if myData and myData.mySelfTime and not System.isUnixTimeSameDay(myData.mySelfTime, time) then
                crossDayState = true
            end
        end
    end

    if needClearState or crossDayState then
        gRankMgr_Clear(RANK_DEFINE_OPERATION_41)
        clearOperationWorldData(cfg.act_id)
    end

    local players = LuaHelp.getAllActorList()
    if players then 
        for k, v in ipairs(players) do  
            oper_act_41_login(v, false)
        end
    end

end

-- 活动结束
function oper_act_41_end(cfg)
    local ssVar = System.getStaticVar()
    ssVar.oper_act_41_start = nil
    ssVar.oper_act_41_cmd = nil
    ssVar.oper_act_41_act = nil

    if not cfg then return end
    local config = cfg.config
    if not config then return end
end

-- 打包数据
function oper_act_41_packet_data(sysarg, cfg)
    if not cfg then return end
    local config = cfg.config
    if not config then return end
    
    
    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_41, 1)

    local myData = BaseFuc_unserialize(data)
    

    if not myData then
        myData = {}
    end

    local miniTime = System.getCurrMiniTime()
    local time = System.getSystemTime()

    if not myData.dailyStartTime then
        myData.dailyStartTime = miniTime
    end
    if not myData.onLineTime then
        myData.onLineTime = 0
    end
    if not myData.myDailyUseCount then
        myData.myDailyUseCount = 0
    end
    local totalCount = math.floor((miniTime - myData.dailyStartTime + myData.onLineTime)/config.everyCountPerSecond)

    local moreTime = (miniTime - myData.dailyStartTime + myData.onLineTime) % config.everyCountPerSecond
    local needTime = config.everyCountPerSecond - moreTime
    if totalCount >= config.maxCount then
        totalCount = config.maxCount
        needTime = -1
    end
    local lastCount = totalCount - myData.myDailyUseCount

    if myData.dailyStartTime and myData.dailyStartTime == miniTime then
        if not myData.cmd_id then
            myData.cmd_id = cfg.cmd_id
            myData.act_id = cfg.act_id
            myData.time = time
        end

        myData.mySelfTime = time

        local newData = BaseFuc_serialize(myData)
        gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_41, 1, newData)
    end
    
    local npack = oper_act_alloc_init_data_packet(sysarg, cfg.cmd_id, cfg.act_id)
    if (npack == nil) then
        return
    end
    --print("lastCount ="..lastCount)

    DataPack.writeByte(npack, totalCount)
    DataPack.writeByte(npack, lastCount)
    --print("needTime ="..needTime)
    DataPack.writeShort(npack, needTime)

    local dVar = Actor.getDyanmicVar(sysarg)
    local circle = dVar.oper_act_41_circle or 1
    local index = dVar.oper_act_41_index or 1

    local dataTable, curCicle, curIndex = getOperationWorldData(cfg.act_id, circle, index, config.saveCount)
    dVar.oper_act_41_circle = curCicle
    dVar.oper_act_41_index = curIndex
    if dataTable then
        local len = #dataTable
         --print("len ="..len)
        DataPack.writeByte(npack, len)
        for idx = 1, len do
            DataPack.writeString(npack, dataTable[idx].name)
            DataPack.writeByte(npack, dataTable[idx].type)
            DataPack.writeShort(npack, dataTable[idx].id)
            DataPack.writeInt(npack, dataTable[idx].count)
        end
    else
        --print("11111")
        DataPack.writeByte(npack, 0)
    end

    DataPack.flush(npack) 
end

-- 操作，返回操作结果，0为成功
function oper_act_41_do(sysarg, cfg, clientPkt)
    if cfg == nil then return end
    
    if cfg.state == nil or cfg.state ~= 1 then -- 不在活动中
        Actor.sendTipmsg(sysarg,Lang.ScriptTips.Operation001, ttFlyTip)
        return
    end
    
    local config = cfg.config
    if config == nil then -- 参数错误
        print("error, oper_act_41_do cfg.config confg error")
        return
    end

    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_41, 1)

    local myData = BaseFuc_unserialize(data)
    

    if not myData then
        myData = {}
    end

    local miniTime = System.getCurrMiniTime()
    local time = System.getSystemTime()

    if not myData.dailyStartTime then
        myData.dailyStartTime = miniTime
    end
    if not myData.onLineTime then
        myData.onLineTime = 0
    end
    if not myData.myDailyUseCount then
        myData.myDailyUseCount = 0
    end
    local totalCount = math.floor((miniTime - myData.dailyStartTime + myData.onLineTime)/config.everyCountPerSecond)
    if totalCount >= config.maxCount then
        totalCount = config.maxCount
    end
    local lastCount = totalCount - myData.myDailyUseCount

    if myData.myDailyUseCount >= config.maxCount then
        Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation053, ttFlyTip)
        return
    end

    if lastCount <= 0 then
        Actor.sendTipmsg(sysarg, Lang.ScriptTips.Operation054, ttFlyTip)
        return
    end

    local index, item = GetItemIdxRandExt(config.itemList)
    if IsBagGridEnough(sysarg, {item}) then
        Awards.Give(sysarg,{item},LogIds.OperationLogId041,Lang.LogTips.Operation041)
    else
        local actorId = Actor.getActorId(sysarg)
        local title = Lang.ScriptTips.Operation159
        local content = Lang.ScriptTips.Operation160

        local sex = Actor.getIntProperty(sysarg, PROP_ACTOR_SEX)
        local vocation = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)

        Awards.GiveToMailById(actorId, {item}, title, content, LogIds.OperationLogId041, Lang.LogTips.Operation041, vocation, sex)
    end 

    myData.myDailyUseCount = myData.myDailyUseCount + 1
    if not myData.cmd_id then
        myData.cmd_id = cfg.cmd_id
        myData.act_id = cfg.act_id
        myData.time = time
    end

    myData.mySelfTime = time

    local newData = BaseFuc_serialize(myData)
    gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_41, 1, newData)


    local saveData = {}
    saveData.name = Actor.getName(sysarg)
    saveData.type = item.type
    saveData.id = item.id
    saveData.count = item.count
    setOperationWorldData(cfg.act_id, saveData, config.saveCount)

    oper_act_41_packet_data(sysarg, cfg)
        
end


-- 跨天
function oper_act_41_new_day_arrive(act_id) 
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_41_start then
        return
    end
    if not ssVar.oper_act_41_cmd then
        return
    end
    if not ssVar.oper_act_41_act then
        return
    end
    local cfg = get_oper_act_cfg(ssVar.oper_act_41_cmd, ssVar.oper_act_41_act)
    if not cfg then
        return
    end
    local config = cfg.config
    if not config then return end

    gRankMgr_Clear(RANK_DEFINE_OPERATION_41)

    local players = LuaHelp.getAllActorList()
    if players then 
        for k, v in ipairs(players) do  
            oper_act_41_login(v, true)
        end
    end
end

--登入
function oper_act_41_login(sysarg, nextDayState)
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_41_start then
        return
    end
    if not ssVar.oper_act_41_cmd then
        return
    end
    if not ssVar.oper_act_41_act then
        return
    end
    local cfg = get_oper_act_cfg(ssVar.oper_act_41_cmd, ssVar.oper_act_41_act)
    if not cfg then
        return
    end
    local config = cfg.config
    if not config then return end


    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_41, 1)

    local myData = BaseFuc_unserialize(data)
    

    if not myData then
        myData = {}
    end

    local miniTime = System.getCurrMiniTime()
    local time = System.getSystemTime()

    
    myData.dailyStartTime = miniTime

    if not myData.onLineTime then
        myData.onLineTime = 0
    end
    if not myData.myDailyUseCount then
        myData.myDailyUseCount = 0
    end

    if not myData.cmd_id then
        myData.cmd_id = cfg.cmd_id
        myData.act_id = cfg.act_id
        myData.time = time
    end

    myData.mySelfTime = time

    local newData = BaseFuc_serialize(myData)
    gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_41, 1, newData)

    if nextDayState then
        oper_act_41_packet_data(sysarg, cfg)
    end
end

--登出
function oper_act_41_logout(sysarg)
    local ssVar = System.getStaticVar()
    if not ssVar.oper_act_41_start then
        return
    end
    if not ssVar.oper_act_41_cmd then
        return
    end
    if not ssVar.oper_act_41_act then
        return
    end
    local cfg = get_oper_act_cfg(ssVar.oper_act_41_cmd, ssVar.oper_act_41_act)
    if not cfg then
        return
    end
    local config = cfg.config
    if not config then return end

    local actorid = Actor.getActorId(sysarg)
    local data = gRankMgr_GetValueById(actorid, RANK_DEFINE_OPERATION_41, 1)

    local myData = BaseFuc_unserialize(data)
    

    if not myData then
        myData = {}
    end

    local miniTime = System.getCurrMiniTime()
    local time = System.getSystemTime()

    if not myData.dailyStartTime then
        myData.dailyStartTime = miniTime
    end
    if not myData.onLineTime then
        myData.onLineTime = 0
    end
    if not myData.myDailyUseCount then
        myData.myDailyUseCount = 0
    end

    if not myData.cmd_id then
        myData.cmd_id = cfg.cmd_id
        myData.act_id = cfg.act_id
        myData.time = time
    end

    myData.onLineTime = myData.onLineTime + miniTime - myData.dailyStartTime

    myData.dailyStartTime = miniTime

    myData.mySelfTime = time

    local newData = BaseFuc_serialize(myData)
    gRankMgr_SetRankEx(actorid, RANK_DEFINE_OPERATION_41, 1, newData)
end